package com.topnav.mc.zzd;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.js.lib.exception.CustomException;
import com.js.lib.result.Result;
import com.js.lib.utils.DateUtils;
import com.topnav.mc.admin.entity.Device;
import com.topnav.mc.admin.service.IDeviceService;
import com.topnav.mc.base.mc.McPage;
import com.topnav.mc.uitls.ErrorResultUtil;
import com.topnav.mc.uitls.PermissionGradeUtil;
import com.topnav.mc.uitls.RedisUtil;
import com.topnav.mc.zzd.account.ZzdAccount;
import com.topnav.mc.zzd.account.ZzdAccountUntil;
import com.topnav.mc.zzd.bean.UpdateCount;
import com.topnav.mc.zzd.bean.ZzdUserBean;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.async.DeferredResult;

import javax.annotation.Resource;
import java.net.URLEncoder;
import java.util.*;

/**
 * @Author: kenny
 * @Date: 2024/1/11 17:59
 */
@Slf4j
@RestController
@CrossOrigin
@RequestMapping({"/test/zzd/groupuser","/zzd/groupuser"})
public class ZzdGroupUserController {
    @Resource
    public ZzdApiUrl zzdApiUrl;
    @Autowired
    ZzdAccountUntil zzdAccountUntil;
    @Autowired
    private IDeviceService deviceService;

    /**
     * 从群组中移除用户
     * @param param
     * @return
     */
    @PostMapping({"/remove"})
    @ResponseBody
    public DeferredResult<Result> deleteGroupUser(@RequestBody ZzdUserBean param){
        String start = DateUtils.format(new Date(),"HH:mm:ss.SSS");
        DeferredResult<Result> result = new DeferredResult<Result>(5000L);
        result.onTimeout(()->{
            result.setResult(Result.error(String.format("超时: %s==>%s",start,DateUtils.format(new Date(),"HH:mm:ss.SSS"))));
        });
        Map<String,Object> map = new HashMap<>();
        map.put("group_id",param.getGroupId());
        map.put("user_ids",param.getUserId());
        String url=zzdApiUrl.deleteGroupUser(map);

        ZzdHttpUtil.request(url, null,zzdAccountUntil.getZzdAccount(), new ZzdHttpUtil.ApiCallBack() {
            @Override
            public void onResult(String resultJson) {//成功
                System.out.println(resultJson);
                result.setResult(ZzdHttpUtil.genResult(resultJson));
            }
        },  new ZzdHttpUtil.ApiCallBack() {
            @Override
            public void onResult(String resultJson) {//失败
                System.out.println(resultJson);
                result.setResult(ZzdHttpUtil.genResult(resultJson));
            }
        });
        return result;
    }


    /**
     * 用户加入到群组从
     * @param param
     * @return
     */
    @PostMapping({"/add"})
    @ResponseBody
    public DeferredResult<Result> addGroupUser(@RequestBody ZzdUserBean param){
        String start = DateUtils.format(new Date(),"HH:mm:ss.SSS");
        DeferredResult<Result> result = new DeferredResult<Result>(5000L);
        result.onTimeout(()->{
            result.setResult(Result.error(String.format("超时: %s==>%s",start,DateUtils.format(new Date(),"HH:mm:ss.SSS"))));
        });
        Map<String,Object> map = new HashMap<>();
        map.put("group_id",param.getGroupId());
        map.put("user_ids",param.getUserId()); //用户id，多个以逗号分隔
        String url=zzdApiUrl.newGroupUser(map);
        ZzdHttpUtil.request(url, null,zzdAccountUntil.getZzdAccount(),new ZzdHttpUtil.ApiCallBack() {
            @Override
            public void onResult(String resultJson) {//成功
                System.out.println(resultJson);
                result.setResult(ZzdHttpUtil.genResult(resultJson));
            }
        },  new ZzdHttpUtil.ApiCallBack() {
            @Override
            public void onResult(String resultJson) {//失败
                System.out.println(resultJson);
                result.setResult(ZzdHttpUtil.genResult(resultJson));
            }
        });
        return result;
    }

    /**
     * 查询指定群组下所有用户
     * @param groupId
     * @return
     */
    @GetMapping("/find/users")
    @ResponseBody
    public DeferredResult<Result> queryUserByGroup(String groupId){
        String start = DateUtils.format(new Date(),"HH:mm:ss.SSS");
        DeferredResult<Result> result = new DeferredResult<Result>(5000L);
        result.onTimeout(()->{
            result.setResult(Result.error(String.format("超时: %s==>%s",start,DateUtils.format(new Date(),"HH:mm:ss.SSS"))));
        });
        Map<String,Object> map = new HashMap<>();
        map.put("limit",1000);
        map.put("page",0);
        List<ZzdUserBean> beans = new ArrayList<>();

        map.put("group_id",groupId);
        String url=zzdApiUrl.queryUser(map);
        //查群组下的设备
        ZzdHttpUtil.request(url, null,zzdAccountUntil.getZzdAccount(),new ZzdHttpUtil.ApiCallBack() {
            //群组时的用户查询 成功
            @Override
            public void onResult(String resultJson) {//成功
                JSONObject json = JSONObject.parseObject(resultJson);
                JSONObject data = json.getJSONObject("data");
                Integer total = data.getInteger("total");
                JSONArray users = (JSONArray)data.get("users");

                for(int i=0;i<users.size();i++){
                    JSONObject jd = (JSONObject)users.get(i);
                    ZzdUserBean bean = new ZzdUserBean();
                    bean.setUserAccount(jd.getString("user_account"));
                    bean.setGroupIds(jd.getString("group_ids"));
                    beans.add(bean);
                }
                result.setResult(Result.ok(beans));
            }
        },  new ZzdHttpUtil.ApiCallBack() {
            //群组里的用户查询 失败
            @Override
            public void onResult(String resultJson) {//失败
                System.out.println(resultJson);
                result.setResult(ZzdHttpUtil.genResult(resultJson));
            }
        });
        return result;
    }

    /**
     * 新增或加入群组
     * @param params List<ZzdUserBean></>
     * @return
     */
    @PostMapping({"/addtogroup/or/new"})
    @ResponseBody
    public DeferredResult<Result> registUserOrAndGroup(@RequestBody List<ZzdUserBean> params) throws Exception {
        ZzdAccount zzdAccount = zzdAccountUntil.getZzdAccount();

        String start = DateUtils.format(new Date(),"HH:mm:ss.SSS");
        DeferredResult<Result> result = new DeferredResult<Result>(50000L);
        result.onTimeout(()->{
            result.setResult(Result.error(String.format("网络超时: %s==>%s",start,DateUtils.format(new Date(),"HH:mm:ss.SSS"))));
        });
        if (CollectionUtils.isEmpty(params)){result.setResult(Result.error("参数不全"));}
        String random = (String) RedisUtil.get(ZzdConstant.ZZD_RANDOM_KEY);
        if (random == null){result.setResult(Result.error("第三方系统未登录"));}

        GroupUpdateCount groupUpdateCount = new GroupUpdateCount();
        groupUpdateCount.setTotal(params.size());

        UpdateCount updateCount = new UpdateCount();
        updateCount.setCurr(0);
        updateCount.setTotal(params.size());
        String groupId=null;
        for (ZzdUserBean bean : params){
            groupId = groupId==null?bean.getGroupId():groupId;
            if (!bean.getRegistered()){
                //未注册
                this.newUser(bean,random,groupUpdateCount,updateCount);
                Thread.sleep(200);
            }else{
                if (!StringUtils.isEmpty(bean.getUserId())){
                    groupUpdateCount.addUserIds(bean.getUserId());
                }
            }
        }
        groupUpdateCount.setGroupId(groupId);

        new Thread(()->{
            while (true){
                if (groupUpdateCount.isFull()){
                    //ZzdAccount zzdAccount1 = zzdAccountUntil.getZzdAccount();
                    //加到群组里
                    String userIds = null;
                    for(String userId: groupUpdateCount.getUserIds()){
                        userIds = userIds==null?userId:userIds+","+userId;
                    }
                    groupUpdateCount.getUserIds().clear();
                    try {
                        this.addToGroup(zzdAccount,groupUpdateCount.groupId,userIds,groupUpdateCount.getUserIds().size(),updateCount,result);
                    } catch (Exception e) {
                        if (e instanceof CustomException){
                            CustomException customException = (CustomException)e;
                            result.setResult(ErrorResultUtil.result(customException));
                        }
                    }
                    break;
                }
               try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        }).start();

        return result;
    }

    private void newUser(ZzdUserBean bean,String random,GroupUpdateCount groupUpdateCount,UpdateCount updateCount) throws Exception{
        try{
            //有效订单号
            Object obj=RedisUtil.get(ZzdConstant.ZZD_VALIDBILL_IDS + zzdAccountUntil.getZzdAccount().getAccount());
            Integer billId=1;
            if (obj != null){
                billId = Integer.valueOf(obj.toString().split(",")[0].toString());
            }
            Map<String,Object> map = new HashMap<>();
            map.put("user_account",bean.getUserAccount());
            map.put("pwd",ZzdHttpUtil.sha1("111111"));
            map.put("user_name", URLEncoder.encode(bean.getUserName()));
            map.put("proxy_account",zzdAccountUntil.getZzdAccount().getAccount());
            map.put("proxy_pwd",ZzdHttpUtil.hmacSha1(random, ZzdHttpUtil.sha1(zzdAccountUntil.getZzdAccount().getPassword())));
            map.put("bill_id",billId);
            map.put("bill_type",1);
            map.put("clientType",3);
            map.put("desc",URLEncoder.encode(bean.getUserName()));
            map.put("default_group",bean.getGroupId());
            String url=zzdApiUrl.newUser(map);
            ZzdHttpUtil.request(url, null,zzdAccountUntil.getZzdAccount(),new ZzdHttpUtil.ApiCallBack() {
                @Override
                public void onResult(String resultJson) {//成功
                    log.info(resultJson);
                    JSONObject json = JSONObject.parseObject(resultJson);
                    if (json.getInteger("code") != null) {
                        if (json.getInteger("code") == 0) {
                            Device device = deviceService.getById(bean.getDeviceId());
                            device.setTalkAccount(bean.getUserAccount());
                            device.setTalkId(json.getJSONObject("data").getString("id"));
                            deviceService.updateById(device);
                            //成功
                            JSONObject data = json.getJSONObject("data");
                            String id = data.getString("id");
                            groupUpdateCount.addUserIds(id);
                        }else{
                            groupUpdateCount.userRegisterError();
                            updateCount.updateFaild(1);
                            updateCount.getMsgs().append(bean.getUserAccount()).append(":").append(json.getString("msg")).append(";");
                        }
                    }else{
                        groupUpdateCount.userRegisterError();
                        updateCount.updateFaild(1);
                        updateCount.getMsgs().append(bean.getUserAccount()).append(":").append(resultJson).append(";");
                    }
                    updateCount.updateCurr(1);
                    log.debug(resultJson);
                }
            },  new ZzdHttpUtil.ApiCallBack() {
                @Override
                public void onResult(String resultJson) {//失败
                    //{"code":1,"data":{},"msg":"accountExist"}
                    log.error(resultJson);
                    JSONObject json = JSONObject.parseObject(resultJson);
                    if (json.get("msg") != null){
                        updateCount.getMsgs().append(bean.getUserAccount()).append(":").append(json.getString("msg")).append(";");
                    }else{
                        updateCount.getMsgs().append(bean.getUserAccount()).append(":").append(resultJson).append(";");
                        //updateCount.getMsgs().put(bean.getUserAccount(),resultJson);
                    }
                    groupUpdateCount.userRegisterError();
                    updateCount.updateFaild(1);
                }
            });
        }catch (Exception e){
            log.error(e.toString());
            updateCount.updateFaild(1);
            updateCount.getMsgs().append("error").append(":").append(e.toString()).append(";");
        }
    }

    private void addToGroup(ZzdAccount zzdAccount,String groupId,String userIds,int count,UpdateCount updateCount,DeferredResult result) throws Exception{
        //try{
            Map<String,Object> map = new HashMap<>();
            map.put("group_id",groupId);
            map.put("user_ids",userIds); //用户id，多个以逗号分隔
            String url=zzdApiUrl.newGroupUser(map);
               ZzdHttpUtil.request(url, null,zzdAccount,new ZzdHttpUtil.ApiCallBack() {
                @Override
                public void onResult(String resultJson) {//成功
                    log.info(resultJson);
                    //System.out.println(resultJson);
                    updateCount.updateSuccess(count);
                    result.setResult(Result.ok(updateCount));
                }
            },  new ZzdHttpUtil.ApiCallBack() {
                @Override
                public void onResult(String resultJson) {//失败
                    System.out.println(resultJson);
                    updateCount.updateFaild(count);
                    result.setResult(Result.ok(updateCount));
                }
            });
        //}catch (Exception e){
        //    result.setResult(Result.error(e.toString()));
        //}


    }


    /**
     * 从群组移除设备或从注册移除
     * @param params
     * @return
     */
    @PostMapping({"/removefromgroup/and/delete"})
    @ResponseBody
    public DeferredResult<Result> removeFromGroupAndDelete(@RequestBody List<ZzdUserBean> params){
        //{
        //    "groupId": "886936",
        //    "groupIds": "886936",
        //    "userId": "2984574978"
        //    "userAccount":6051434""
        //}
        String start = DateUtils.format(new Date(),"HH:mm:ss.SSS");
        DeferredResult<Result> result = new DeferredResult<Result>(5000L);
        result.onTimeout(()->{
            result.setResult(Result.error(String.format("超时: %s==>%s",start,DateUtils.format(new Date(),"HH:mm:ss.SSS"))));
        });
        String userIds=null;String groupId=null;
        List<ZzdUserBean> delDevices = new ArrayList<>();
        for(ZzdUserBean param : params){
            groupId=groupId==null?param.getGroupId():groupId;
            userIds = userIds == null?param.getUserId():userIds + "," + param.getUserId();
            if (groupId.equals(param.getGroupIds())){
                delDevices.add(param);
            }
        }
        Map<String,Object> map = new HashMap<>();
        map.put("group_id",groupId);
        map.put("user_ids",userIds);
        String url=zzdApiUrl.deleteGroupUser(map);
        //移除
        ZzdHttpUtil.request(url, null,zzdAccountUntil.getZzdAccount(), new ZzdHttpUtil.ApiCallBack() {
            @Override
            public void onResult(String resultJson) {//成功
                //从群组移出成功
                System.out.println(resultJson);
                //没有群组的用户删除
                String delIds=null;
                if (delDevices.size() > 0) {
                    for (ZzdUserBean bean : delDevices) {
                        delIds = delIds == null ? bean.getUserId() : delIds + "," + bean.getUserId();
                    }
                    Map<String, Object> map1 = new HashMap<>();
                    map1.put("user_ids", delIds);
                    String url1 = zzdApiUrl.deleteUser(map1);
                    ZzdHttpUtil.request(url1, null, zzdAccountUntil.getZzdAccount(), new ZzdHttpUtil.ApiCallBack() {
                        @Override
                        public void onResult(String resultStr) {
                            //删除成功
                            System.out.println(resultStr);
                            //更新本地设备的talkAccount和talkId
                            for (ZzdUserBean bean : delDevices) {
                                LambdaUpdateWrapper<Device> wrapper = new LambdaUpdateWrapper<Device>().set(Device::getTalkAccount,null).set(Device::getTalkId,null).eq(Device::getTalkAccount,bean.getUserAccount());
                                deviceService.update(wrapper);
                            }
                            result.setResult(ZzdHttpUtil.genResult(resultStr));
                        }
                    }, new ZzdHttpUtil.ApiCallBack() {
                        @Override
                        public void onResult(String resultJson) {//失败
                            System.out.println(resultJson);
                            result.setResult(ZzdHttpUtil.genResult(resultJson));
                        }
                    });
                }
            }
        },  new ZzdHttpUtil.ApiCallBack() {
            @Override
            public void onResult(String resultJson) {//失败
                System.out.println(resultJson);
                result.setResult(ZzdHttpUtil.genResult(resultJson));
            }
        });


        return result;
    }

    @Data
    public class GroupUpdateCount{
        private String groupId;
        private List<String> userIds=new ArrayList<>();
        private int total=0;

        public synchronized void addUserIds(String userId){
            this.userIds.add(userId);
        }

        public synchronized void userRegisterError(){
            if (this.total > 0)
                this.total--;
        }

        public boolean isFull(){return this.userIds.size() >= this.total;}
    }
}
